import { MODEL_SERVER_URL, PropertyKey } from "@/constants/constants";
import { RouterName } from "@/views/router";
import { SimulateController } from "./Controller";
import { ImageInfo, RoughImage, WinPraram } from "./types/ImageSwitcher";
import { SimFrameToSubChannel, SubWinName } from "./types/Win";

export class ImageSwitcherService {

  showEmpty = false
  switchImages: ImageInfo[] = []
  switchImagesMap = new Map<string, ImageInfo[]>()
  winparams = {} as WinPraram

  controller: SimulateController;

  constructor(c: SimulateController) {
    this.controller = c;
  }

  async dealImageInfo(images: RoughImage[], keys: PropertyKey[], winparams = this.winparams) {
    const r = [];
    if (images && images.length) {
      for (const image of images) {
        const imageinfo = {} as ImageInfo;
        // active image dosen't have active element, but has the signal
        imageinfo.url = image.icon.includes('ActiveImage.svg')
          ? ''
          : `${MODEL_SERVER_URL}public/files/${winparams.projectId}/${image.icon}`;
        const propertyValuse = (await this.controller.modelApi.modelPropertyListByKeys({
          projectId: winparams.projectId,
          modelId: image.id,
          keys
        })).data?.data;
        for (const pv of propertyValuse) {
          switch (pv.key) {
            case PropertyKey.ActiveImage_ActiveElement:
              imageinfo.statusId = pv.value ? pv.value.id : '';
              break;
            case PropertyKey.ActiveImage_OnClick:
              imageinfo.signal = pv.value
                ? {
                  elementId: pv.value.id,
                  simulationSessionId: winparams.sessionId,
                  contextId: winparams.instanceId,
                }
                : undefined;
              break;
            default:
              break;
          }
        }
        r.push(imageinfo);
      }
    }
    return r;
  }

  private async getImagesAndShowEmptyImageForUnspecifiedValue(keys: PropertyKey[]) {
    const configRes = (await this.controller.modelApi.modelPropertyListByKeys({
      projectId: this.winparams.projectId,
      modelId: this.winparams.uiId,
      keys,
    })).data?.data;

    if (configRes && configRes.length) {
      for (const c of configRes) {
        switch (c.key) {
          case PropertyKey.ImageSwitcher_ShowEmptyImageForUnspecifiedValue:
            this.showEmpty = c.value ? true : false;
            break;
          // case PropertyKey.Class_nestedClassifier: // if empty use Class_ownedAttribute
          case PropertyKey.Class_ownedAttribute:
            {
              const usedImageDatas = c.value && c.value.length ? c.value : configRes[configRes.length - 1].value;
              const imageInfos = await this.dealImageInfo(
                usedImageDatas,
                [PropertyKey.ActiveImage_ActiveElement, PropertyKey.ActiveImage_OnClick]
              );
              if (imageInfos.length) {
                this.switchImages.push(...imageInfos);
              }
            }
            break;
          default:
        }
      }
    }
  }

  async subWinOpen(p: WinPraram) {
    await this.controller.winService.openPluginSubWin(
      RouterName.ImageSwitcher,
      { width: 400, height: 400, skipTaskbar: true, title: SubWinName.ImageSwitcher },
      p
    );
  }

  async pageInit() {
    this.winparams = this.controller.winService.getQueryParams() as WinPraram;
    await this.getImagesAndShowEmptyImageForUnspecifiedValue([
      PropertyKey.ImageSwitcher_ShowEmptyImageForUnspecifiedValue,
      // PropertyKey.Class_nestedClassifier, 分类器信息不再从嵌套分类器中查找，改为再Class_ownedAttribute（拥有属性）中查找
      PropertyKey.Class_ownedAttribute,
    ]);
    console.info("switchImages: ", this.switchImages);
    console.info("showEmpty: ", this.showEmpty);
  }

  doSwitch(modelId: string) {
    // both imageswitch and frameui need to deal this
    const winsFlag = [SubWinName.ImageSwitcher, SubWinName.UIFrame];
    const msgInfo = {
      type: SimFrameToSubChannel.ImageSwitcherSwitch,
      data: modelId
    };
    for (const f of winsFlag) {
      const win = this.controller.winService.getSubWinsByName(f);
      if (win.length) {
        this.controller.winService.sendInfoToSubWins(
          msgInfo,
          f
        );
      }
    }
  }
}
